package com.groupname.dangerousdelves;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Map;

/**
 *  This class is responsible for manager events in the game. It receives
 *  event data and transmits that data to all relevant listeners.
 *
 *  @author Chris Fieldman (Chrisf90)
 *  @version 2012.11.03
 */
public class EventManager
{
    //~-------------------------------------------------------------------------
    // Member Variables
    private static LinkedList<IEventData> eventQueue;
    private static Map<EventType, ArrayList<IEventListener>> eventListenerMap;

    //~-------------------------------------------------------------------------
    // Constructors
    /**
     * Create a new EventManager object.
     */
    public EventManager()
    {
        //this.eventListenerMap = new Map<EventType, IEventListener>();
    }

    //~-------------------------------------------------------------------------
    // Methods
    /**
     * Registers an event type with the event manager.
     * @param type The event type to register
     */
    public void registerEvent(EventType type)
    {
        if (validateType(type))
        {
            //trigger exception - can't register an event twice.
        }

        ArrayList<IEventListener> listeners = new ArrayList<IEventListener>();
        eventListenerMap.put(type, listeners);
    }

    // ----------------------------------------------------------
    /**
     * Validates that an event type has been registered.
     * @param type The type of event to validate
     * @return True if the event has been registered, false otherwise
     */
    public static boolean validateType(EventType type)
    {
        return eventListenerMap.containsKey(type);
    }

    // ----------------------------------------------------------
    /**
     * Adds an event listener to the event listener map.
     * @param type The type of event to attach to the event listener
     * @param listener The listener to add to the map
     */
    public static void addListener(EventType type, IEventListener listener)
    {
        if (!validateType(type))
        {
            // trigger exception.
        }

        eventListenerMap.get(type).add(listener);
    }

    // ----------------------------------------------------------
    /**
     * Triggering an event causes it to be immediately fired off to the event
     * listeners.
     * @param data The event data to send off
     */
    public static void triggerEvent(IEventData data)
    {
        EventType type = data.getEventType();
        if (!validateType(type))
        {
            // trigger exception
        }

        ArrayList<IEventListener> listenerList = eventListenerMap.get(type);
        if (listenerList.isEmpty())
        {
            // trigger exception
        }

        for (IEventListener listener : listenerList)
        {
            listener.processEvent(data);
        }
    }

    // ----------------------------------------------------------
    /**
     * Queuing an event adds it to a queue to be processed later.
     * @param data The event data to queue
     */
    public static void queueEvent(IEventData data)
    {
        EventType type = data.getEventType();
        if (!validateType(type))
        {
            // trigger exception
        }

        eventQueue.addLast(data);
    }

    // ----------------------------------------------------------
    /**
     * Processes events in the queue and sends them off to their listeners
     */
    public void processEventQueue()
    {
        while (!eventQueue.isEmpty())
        {
            IEventData data = eventQueue.removeFirst();
            triggerEvent(data);
        }
    }
}